﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using BrainTechLLC.Silverlight.InputControls;

namespace BrainTechLLC.Silverlight.InputControls2
{
    [TemplatePart(Name = "txtInput", Type = typeof(FilteredTextBox))]
    [TemplatePart(Name = "gridMain", Type = typeof(Grid))]
    [TemplatePart(Name = "stack", Type = typeof(StackPanel))]
    public partial class InputTextBox : InputBaseControl, IInputControl2
    {
        protected FilteredTextBox _txtInput;
        protected Grid _gridMain;
        protected StackPanel _stack;

        public static readonly DependencyProperty DataTypeProperty = DependencyProperty.Register(
            "DataType", typeof(DataType), typeof(InputTextBox), new PropertyMetadata(new PropertyChangedCallback(DataTypeChanged)));

        public static readonly DependencyProperty FormatProperty = DependencyProperty.Register(
            "Format", typeof(TextFormat), typeof(InputTextBox), new PropertyMetadata(new PropertyChangedCallback(FormatChanged)));

        public static readonly DependencyProperty MaskProperty = DependencyProperty.Register(
            "Mask", typeof(string), typeof(InputTextBox), new PropertyMetadata(new PropertyChangedCallback(MaskChanged)));

        public static readonly DependencyProperty ShowPromptProperty = DependencyProperty.Register(
            "ShowPrompt", typeof(bool), typeof(InputTextBox), new PropertyMetadata(true, new PropertyChangedCallback(ShowPromptChanged)));

        public static readonly DependencyProperty TextBoxWidthProperty = DependencyProperty.Register(
            "TextBoxWidth", typeof(GridLength), typeof(InputTextBox),
            new PropertyMetadata(new GridLength(160, GridUnitType.Pixel), new PropertyChangedCallback(TextBoxWidthChanged)));

        public static readonly DependencyProperty TextBoxFontSizeProperty = DependencyProperty.Register(
            "TextBoxFontSize", typeof(double), typeof(InputTextBox), new PropertyMetadata(10.0, new PropertyChangedCallback(TextBoxFontSizePropChanged)));

        public static readonly DependencyProperty TextForegroundProperty = DependencyProperty.Register(
            "TextForeground", typeof(Brush), typeof(InputTextBox),
            new PropertyMetadata(new SolidColorBrush(Colors.Black), new PropertyChangedCallback(TextForegroundChanged)));

        public static readonly DependencyProperty TextBoxPaddingProperty = DependencyProperty.Register(
            "TextBoxPadding", typeof(Thickness), typeof(InputTextBox),
            new PropertyMetadata(new Thickness(2, 1, 2, 1), new PropertyChangedCallback(TextBoxPaddingChanged)));

        public static readonly DependencyProperty PasswordCharProperty = DependencyProperty.Register(
            "PasswordChar", typeof(string), typeof(InputTextBox),
            new PropertyMetadata(string.Empty, new PropertyChangedCallback(PasswordCharChanged)));

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            "Text", typeof(string), typeof(InputTextBox),
            new PropertyMetadata(string.Empty, new PropertyChangedCallback(TextChanged)));

        public static readonly DependencyProperty TextWrappingModeProperty = DependencyProperty.Register(
            "TextWrappingMode", typeof(TextWrapping), typeof(InputTextBox),
            new PropertyMetadata(TextWrapping.NoWrap, new PropertyChangedCallback(TextWrappingModeChanged)));

        public TextWrapping TextWrappingMode
        {
            get { return (TextWrapping)GetValue(TextWrappingModeProperty); }
            set { SetValue(TextWrappingModeProperty, value); }
        }

        private static void TextWrappingModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            InputTextBox t = (InputTextBox)d;
            t.TextWrappingMode = (TextWrapping)e.NewValue;
            t.UpdateTextWrappingMode();
        }

        public void UpdateTextWrappingMode()
        {
            if (_txtInput != null)
            {
                _txtInput.TextWrappingMode = TextWrappingMode;
            }
        }


        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            InputTextBox t = (InputTextBox)d;
            t.Text = (string)e.NewValue;
            t.UpdateText();
        }

        public void UpdateText()
        {
            if (_txtInput != null)
            {
                _txtInput.Text = Text;
            }
        }

        public string PasswordChar
        {
            get { return (string)GetValue(PasswordCharProperty); }
            set { SetValue(PasswordCharProperty, value); }
        }

        private static void PasswordCharChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            InputTextBox t = (InputTextBox)d;
            t.PasswordChar = (string)e.NewValue;
            t.UpdatePasswordChar();
        }

        public void UpdatePasswordChar()
        {
            if (_txtInput != null)
                _txtInput.PasswordChar = PasswordChar.Length > 0 ? PasswordChar[0] : (char)0;
        }

        public Thickness TextBoxPadding
        {
            get { return (Thickness)GetValue(TextBoxPaddingProperty); }
            set { SetValue(TextBoxPaddingProperty, value); }
        }

        private static void TextBoxPaddingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            InputTextBox t = (InputTextBox)d;
            t.TextBoxPadding = (Thickness)e.NewValue;
            t.UpdateTextBoxPadding();
        }

        public void UpdateTextBoxPadding()
        {
            if (_txtInput != null)
                _txtInput.Padding = TextBoxPadding;
        }

        public Brush TextForeground
        {
            get { return (Brush)GetValue(TextForegroundProperty); }
            set { SetValue(TextForegroundProperty, value); }
        }

        private static void TextForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            InputTextBox t = (InputTextBox)d;
            t.TextForeground = e.NewValue as Brush;
            t.UpdateTextForeground();
        }

        public void UpdateTextForeground()
        {
            if (_txtInput != null)
                _txtInput.Foreground = TextForeground;
        }

        public double TextBoxFontSize
        {
            get { return (double)GetValue(TextBoxFontSizeProperty); }
            set { SetValue(TextBoxFontSizeProperty, value); }
        }

        private static void TextBoxFontSizePropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            InputTextBox t = (InputTextBox)d;
            t.TextBoxFontSize = (double)e.NewValue;
            t.UpdateTextBoxFontSize();
        }

        public void UpdateTextBoxFontSize()
        {
            if (_txtInput != null)
                _txtInput.FontSize = TextBoxFontSize;
        }

        public DataType DataType
        {
            get { return (DataType)GetValue(DataTypeProperty); }
            set { SetValue(DataTypeProperty, value); }
        }

        public TextFormat Format
        {
            get { return (TextFormat)GetValue(FormatProperty); }
            set { SetValue(FormatProperty, value); }
        }

        public string Mask
        {
            get { return (string)GetValue(MaskProperty); }
            set { SetValue(MaskProperty, value); }
        }

        public GridLength TextBoxWidth
        {
            get { return (GridLength)GetValue(TextBoxWidthProperty); }
            set { SetValue(TextBoxWidthProperty, value); }
        }

        public bool ShowPrompt
        {
            get { return (bool)GetValue(ShowPromptProperty); }
            set { SetValue(ShowPromptProperty, value); }
        }

        private static void ShowPromptChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((InputTextBox)d).ShowPrompt = (bool)e.NewValue;
            ((InputTextBox)d).UpdateShowPrompt();
        }

        private static void DataTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((InputTextBox)d).DataType = (DataType)e.NewValue;
            ((InputTextBox)d).UpdateDataTypeBinding();
        }

        private static void FormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((InputTextBox)d).Format = (TextFormat)e.NewValue;
            ((InputTextBox)d).UpdateFormatChanged();
        }

        private static void MaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((InputTextBox)d).Mask = e.NewValue as string;
            ((InputTextBox)d).UpdateMaskChanged();
        }

        private static void TextBoxWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((InputTextBox)d).Mask = e.NewValue as string;
            ((InputTextBox)d).UpdateTextBoxWidthChanged();
        }

        public void UpdateTextBoxWidthChanged()
        {
            if (_gridMain != null)
            {
                _gridMain.ColumnDefinitions[1].Width = TextBoxWidth;
            }
        }

        public void UpdateDataTypeBinding()
        {
            if (_txtInput != null)
            {
                _txtInput.DataType = DataType;
                _base.SetInputControlBehavior(_txtInput, DataType, Format);
            }
        }

        public void UpdateFormatChanged()
        {
            if (_txtInput != null)
            {
                _txtInput.Format = Format;
                _base.SetInputControlBehavior(_txtInput, DataType, Format);
            }
        }

        public void UpdateShowPrompt()
        {
            if (_stack != null)
            {
                _stack.Visibility = ShowPrompt ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public void UpdateMaskChanged()
        {
            if (_txtInput != null && Mask != null)
                _txtInput.Mask = Mask;
        }

        protected override void UpdateValidatingType()
        {
            if (_txtInput != null)
            {
                _txtInput.ValidatingType = ValidatingType;
                _txtDateHint.Visibility = (ValidatingType == typeof(DateTime) && ShowDateHint == true) ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public override void UpdateBackgroundForInputControlFocus()
        {
            if (_txtInput != null) _txtInput.BackgroundForInputControlFocus = BackgroundForControlFocus;
        }

        /// <summary>
        /// Returns the primary child control responsible for receiving user input
        /// </summary>
        public override Control PrimaryInputControl { get { return _txtInput; } }

        public InputTextBox()
            : base()
        {
            DefaultStyleKey = typeof(InputTextBox);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _txtInput = base.GetTemplateChild("txtInput") as FilteredTextBox;
            _gridMain = base.GetTemplateChild("gridMain") as Grid;
            _stack = base.GetTemplateChild("stack") as StackPanel;

            _txtInput.ParentControl = this;

            _txtInput.GotFocus += new RoutedEventHandler(txtInput_GotFocus);
            _txtInput.KeyUp += new KeyEventHandler(txtInput_KeyUp);
            _txtInput.KeyDown += new KeyEventHandler(txtInput_KeyDown);
            _txtInput.LostFocus += new RoutedEventHandler(txtInput_LostFocus);

            _txtInput.FontSize = 8.5f;

            UpdateValidatingType();
            UpdateDataTypeBinding();
            UpdateMaskChanged();
            UpdateFormatChanged();
            UpdateShowPrompt();
            UpdateTextBoxWidthChanged();
            UpdateTextForeground();
            UpdateTextBoxFontSize();
            UpdateTextBoxPadding();            
            UpdateText();
            UpdatePasswordChar();
        }

        public string ReadPassword()
        {
            return (_txtInput != null) ? _txtInput.ReadPassword() : string.Empty;
        }

        private void txtInput_LostFocus(object sender, RoutedEventArgs e)
        {
            OnValueChanged(Value);
            // Revalidate();
        }

        public override string ValidateContents()
        {
            return _base.ValidateContents(this, DataType, Format, ValidationType);
        }

        public override string Value
        {
            get
            {
                string text = string.Empty;

                if (_txtInput != null)
                {
                    text = _txtInput.Text.Trim();

                    if (!_txtInput.MaskFull)
                    {
                        if (text == _txtInput.Mask.Replace("9", " ").Replace("0", " ").Trim())
                            return string.Empty;

                        return text;
                    }
                }
                return text;
                //return (ProfileElement as ProfileElement).GetVOFormatted(text);
            }
            set
            {
                Text = value;

                if (_txtInput != null && Value != value)
                {
                    //txtInput.Text = (ProfileElement as ProfileElement).GetScreenFormatted(txtInput.ValidatingType, value);
                    _txtInput.Text = value;
                    OnValueChanged(value);
                }
            }
        }

        private void txtInput_KeyDown(object sender, KeyEventArgs e)
        {
        }

        private void txtInput_KeyUp(object sender, KeyEventArgs e)
        {
            // HEREHERE
        }

        private void txtInput_GotFocus(object sender, RoutedEventArgs e)
        {
            //if (!ShiftKeyDown)
            //    _txtInput.Focus();
            //App.MainPage.mainReviewView.HandleAdjustScroll(this);
        }
    }
}


